package com.dzu.medium;

import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
import java.util.List;

/**
 * @author ZhaoDong
 * @date 2022/12/28 10:38
 * @description leetcode
 */
public class Test227 {
    public static void main(String[] args) {
        System.out.println(calculate2("3+2*2"));
        System.out.println(calculate(" 3+5 / 2 "));
        System.out.println(calculate("42"));
        System.out.println(calculate("1-1+1"));
//
        System.out.println(calculate("1*2-3/4+5*6-7*8+9/10"));
        System.out.println(calculate("2-0+30-56+0"));
        System.out.println(calculate("282-1*2*13-30-2*2*2/2-95/5*2+55+804+3024"));

    }


    public static int calculate2(String s) {
        Deque<Integer> number = new ArrayDeque<>();
        char perOperator = '+';
        int num = 0;
        int length = s.length();
        for (int i = 0; i < length; i++) {
            char chr = s.charAt(i);
            if (Character.isDigit(chr)) {
                num = num * 10 + chr - '0';
            }

            if (!Character.isDigit(chr) && chr != ' ' || i == length - 1) {
                switch (perOperator) {
                    case '+':
                        number.addLast(num);
                        break;
                    case '-':
                        number.addLast(-num);
                        break;
                    case '*':
                        number.addLast(number.removeLast() * num);
                        break;
                    default:
                        number.addLast(number.removeLast() / num);
                }
                perOperator = chr;
                num = 0;
            }
        }
        int res = 0;
        while (!number.isEmpty()) {
            res += number.removeLast();
        }

        return res;


    }


    public static int calculate(String s) {

        List<String> list = Arrays.asList("+", "-", "*", "/");

        Deque<Integer> number = new ArrayDeque<>();
        Deque<String> operator = new ArrayDeque<>();

        boolean flag = false;

        for (String str : s.split("")) {
            if (str.equals("") || str.equals(" ")) {
                flag = false;
                continue;
            }
            if (list.contains(str)) {
                flag = false;
                if (!operator.isEmpty()) {
                    String op = operator.getLast();
                    if (priority(op, str)) {
                        String op1 = operator.removeLast();
                        Integer n2 = number.removeLast();
                        Integer n1 = number.removeLast();
                        number.addLast(cal(n1, n2, op1));
                        operator.addLast(str);
                    } else {
                        operator.addLast(str);
                    }

                } else {
                    operator.addLast(str);
                }
            } else {
                if (flag) {
                    Integer n = number.removeLast();
                    number.addLast(n * 10 + Integer.parseInt(str));
                } else {
                    flag = true;
                    number.addLast(Integer.valueOf(str));
                }
            }
        }
        if (!operator.isEmpty()) {
            String op = operator.getLast();
            if (op.equals("*") || op.equals("/")) {
                operator.removeLast();
                Integer n2 = number.removeLast();
                Integer n1 = number.removeLast();

                number.addLast(cal(n1, n2, op));
            }
        }

        while (!operator.isEmpty()) {
            number.addFirst(cal(number.removeFirst(), number.removeFirst(), operator.removeFirst()));
        }
        return number.getFirst();

    }

    private static Integer cal(Integer n1, Integer n2, String op) {
        switch (op) {
            case "+":
                return n1 + n2;
            case "*":
                return n1 * n2;
            case "-":
                return n1 - n2;
            case "/":
                return n1 / n2;
            default:
                throw new RuntimeException();
        }
    }

    public static boolean priority(String op1, String op2) {
        if ((op1.equals("*") || op1.equals("/")) && (op2.equals("*") || op2.equals("/"))) {
            return true;
        }

        if ((op1.equals("*") || op1.equals("/")) && (op2.equals("+") || op2.equals("-"))) {
            return true;
        }
        return false;

    }

}
